<template>
    <div class="f-slides"
         @mouseenter="onMouseenter" @mouseleave="onMouseleave"
         @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
        <div class="f-slides-window" ref="window">
            <div class="f-slides-wrapper">
                <slot></slot>
            </div>
        </div>
        <div class="f-slides-dots">
            <span @click="onClickPrev">
                <f-icon name="left"></f-icon>
            </span>
            <!--<span v-for="(child,index) in $children" :class="{active:selectedIndex===index}" @click="select(index)">
                {{index}}
            </span>-->
            <span v-for="n in childrenLength" :class="{active:selectedIndex===n-1}" @click="select(n-1)">
                {{n}}
            </span>
            <span @click="onClickNext">
                <f-icon name="right"></f-icon>
            </span>
        </div>
    </div>
</template>

<script>
  import FIcon from './icon';
  export default {
    name: "f-slides"
    ,components:{FIcon}
    ,props:{
      selected:{
        type:String
      }
      ,autoPlay:{
        type:Boolean
        ,default:true
      }
      ,autoPlayDelay:{
        type:Number
        ,default:3000
      }
    }
    ,data(){
      return {
        childrenLength:0
        ,lastSelectedIndex:undefined
        ,timerId:undefined
        ,startTouch:undefined
      }
    }
    ,computed:{
      selectedIndex(){
        let cur = this.names.indexOf(this.selected);
        return cur < 0 ? 0 : cur;
      }
      ,names(){
        return this.items.map(vm => vm.name);
      }
      ,items(){
        return this.$children.filter(vm => vm.$options.name === 'f-slides-item');
      }
    }
    ,mounted() {
      this.updateChildren();
      this.autoPlay && this.playAutomatically();
      this.childrenLength = this.items.length;
    }
    ,updated() {
      this.updateChildren();
    }
    ,methods:{
      updateChildren(){
        let selected = this.getSelected();
        this.items.forEach((vm) => {
          let reverse = this.selectedIndex > this.lastSelectedIndex ? false : true;
          if(this.timerId){
            if(this.lastSelectedIndex === this.childrenLength-1&&this.selectedIndex===0){
              reverse = false;
            }
            if(this.lastSelectedIndex === 0&&this.selectedIndex===this.childrenLength-1){
              reverse = true;
            }
          }
          vm.reverse = reverse;
          this.$nextTick(()=>{ //确保做动画之前 reverse已经生效
            vm.selected = selected;
          })
        });
      }
      ,playAutomatically(){
        if(this.timerId) return;
        let run = () => {
          let index = this.names.indexOf(this.getSelected());
          let newIndex = index + 1;
          // if(newIndex === -1) newIndex = this.names.length - 1;
          // if(newIndex === this.names.length) newIndex = 0;
          this.select(newIndex);
          this.timerId = setTimeout(run, this.autoPlayDelay);
        };
        this.timerId = setTimeout(run,this.autoPlayDelay)
      }
      ,onMouseenter(){
        this.pause();
      }
      ,onMouseleave(){
        this.playAutomatically();
      }
      ,pause(){
        window.clearTimeout(this.timerId);
        this.timerId = null;
      }
      ,onTouchStart(e){
        this.pause();
        if(e.touches.length>1) return;
        this.startTouch = e.touches[0];
      }
      ,onTouchMove(){

      }
      ,onTouchEnd(e){
        let endTouch = e.changedTouches[0];
        let {clientX: x1, clientY: y1} = this.startTouch;
        let {clientX: x2, clientY: y2} = endTouch;
        let distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
        let deltaY = Math.abs(y2-y1);
        let rate = distance / deltaY;
        if(rate>2){
            if(x2>x1){
              //TODO 手机上貌似应该是反方向
              this.select(this.selectedIndex + 1);
            }else{
              this.select(this.selectedIndex - 1);
            }
        }
        this.$nextTick(()=>{
          this.playAutomatically(); //TODO 应该判断是否为autoPlay
        })
      }
      ,onClickPrev(){
        this.select(this.selectedIndex - 1);
      }
      ,onClickNext(){
        this.select(this.selectedIndex + 1);
      }
      ,getSelected(){
        let first = this.items[0];
        return this.selected||first.name;
      }
      ,select(newIndex){
        if(newIndex === -1) newIndex = this.names.length - 1;
        if(newIndex === this.names.length) newIndex = 0;
        this.lastSelectedIndex = this.selectedIndex;
        this.$emit('update:selected', this.names[newIndex]);
      }
    }

  }
</script>

<style lang="scss">
    .f-slides{
        /*display:inline-block;*/
        border:1px solid black;
        &-window{
            overflow:hidden;
        }
        &-wrapper{
            position:relative;
        }
        &-dots{
            padding:8px 0;
            display:flex;
            justify-content: center;
            align-content: center;
            >span{
                width:20px;
                height: 20px;
                border-radius:50%;
                background:#ddd;
                display:inline-flex;
                justify-content: center;
                align-items: center;
                margin:0 8px;
                font-size:12px;
                &:hover{cursor:pointer;}
                &.active{background:black;color:white;cursor:default;}
            }
        }
    }
</style>
